package org.mobilesynergies.android.epic.service;

import org.mobilesynergies.android.epic.service.interfaces.IApplicationStatusChangeCallback;
import org.mobilesynergies.android.epic.service.interfaces.IEpicServiceApplicationInterface;
import org.mobilesynergies.android.epic.service.interfaces.IIncomingMessageCallback;
import org.mobilesynergies.android.epic.service.interfaces.IServiceStatusChangeCallback;

import android.os.Bundle;
import android.os.RemoteException;

/**
* This is the application interface for the epic service. 
* It provides methods for application binding and message exchange.
*   
*/

public abstract class EpicServiceApplicationInterface extends IEpicServiceApplicationInterface.Stub {
	
	/**
	* Get the version of the service running
	*/		
	public abstract int getVersion() throws RemoteException;

	/**
	* Get access to the users EPIC network
	* The application provides the secret applicationKey that uniquely identifies it and the according password.
	* The service verifies the key with the server and waits until all devices have verified it.
	* Subsequently messages are only exchanged with other application nodes of this application.
	* The service returns a sessionKey that is used afterwards by the application nodes for each interaction with the service.
	*
	* @param applicationKey This key is shared by all nodes of an application. It is up to the application developer to keep this key secret.
	* @param applicationPassword This password authenticates the applicationKey
	* @param applicationManifest An XML string that identifies the different application nodes and describes the message exchange types of the individual application nodes
	*
	* @return A sessionKey that allows the application nodes to receive and send messages to/from other application nodes 
	*/
	public abstract String bindApplication(String applicationKey, String applicationPassword, String applicationManifest) throws RemoteException;

	/**
	 * Get a session token for a specific application node. 
	 * The application must have the appropriate permissions to execute the role of the application node 
	 * 
	 * @param sessionKey the sessionKey for this application (received from a successful call to bindApplication)
	 *
	 * @return A sessionToken that will be used for each interaction of a application node with the service 
	 */ 
	public abstract String getSessionToken(String sessionKey, String applicationNodeId) throws RemoteException;
	
	/**
	 * Start to listen for incoming messages and delivers them via the specified IIncomingMessageCallback
	 * This call requires the application to have the according permission.
	 * 
	 * @param sessionToken The sessionToken that identifies the application node (received from a successful call to getSessionToken)
	 * @param messageCallback A IIncomingMessageCallback that is used to deliver the messages when they arrive
	 * @param publisherId The Id of the application node that is specified as a publisher in the manifest xml file
	 * 
	 */
	public abstract void listenForMessages(String sessionToken, IIncomingMessageCallback messageCallback, String publisherId) throws RemoteException;
	
	/**
	 * Register a callback for application status changes. The application gets informed if the service becomes unavailable or available.
	 *
	 * @param sessionKey the sessionKey for this application (received from a successful call to bindApplication)
	 * @param callback A IApplicationStatusChangeCallback that is called on changes of the application state. 
	 */
	public abstract void registerApplicationStatusChangeCallback(String sessionKey, IApplicationStatusChangeCallback callback) throws RemoteException;

	/**
	 * Register a callback for service status changes. The application gets informed if the service becomes unavailable or available.
	 *
	 * @param sessionKey the sessionKey for this application (received from a successful call to bindApplication)
	 * @param callback A IServiceStatusChangeCallback that is called on changes of the service state. 
	 */
	public abstract void registerServiceStatusChangeCallback(String sessionKey, IServiceStatusChangeCallback callback) throws RemoteException;
	
	/**
	 * Request a response. This function is blocking (synchronous).
	 * This call requires the application to have the according permissions.
	 * 
	 * @param sessionToken The sessionToken identifying the application node (received from a successful call to getSessionToken
	 * @param object A Bundle containing the request parameters.  
	 *
	 * @return Returns a Bundle containing the response. 
	 */
	public abstract Bundle requestResponse(String sessionToken, Bundle object) throws RemoteException;

	/**
	 * Send a message to other application nodes.
	 * This call requires the application to have the according permission.
	 * 
	 * @param sessionToken The sessionToken identifying the application node (received from a successful call to getSessionToken
	 * @param object A Bundle containing the structured information required by the application. The Bundle will be serialized and transmitted to other devices. Other application nodes will receive the deserialized Bundle. 
	 */
	public abstract void sendMessage(String sessionToken, Bundle object) throws RemoteException;

	/**
	 * Stop listening for messages sent to this application node
	 *
	 * @param sessionToken The sessionToken identifying the application node (received from a successful call to getSessionToken
	 */		
	public abstract void stopListening(String sessionToken) throws RemoteException;
	
}
